package com.cencat.order.controller;

import com.cencat.common.annotation.Log;
import com.cencat.common.core.controller.BaseController;
import com.cencat.common.core.domain.AjaxResult;
import com.cencat.common.core.page.TableDataInfo;
import com.cencat.common.enums.BusinessType;
import com.cencat.common.utils.poi.ExcelUtil;
import com.cencat.order.domain.Merchant;
import com.cencat.order.domain.MerchantDriver;
import com.cencat.order.domain.MerchantOrder;
import com.cencat.order.domain.vo.MerchantVO;
import com.cencat.order.domain.vo.MerchantStatisticsVO;
import com.cencat.order.domain.vo.MerchantAnalysisVO;
import com.cencat.order.domain.dto.MerchantCreateDTO;
import com.cencat.order.domain.dto.MerchantUpdateDTO;
import com.cencat.order.domain.dto.MerchantDriverBindDTO;
import com.cencat.order.domain.dto.QuickOrderDTO;
import com.cencat.order.service.IMerchantService;
import com.cencat.order.service.IMerchantDriverService;
import com.cencat.order.service.IMerchantOrderService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * 固定商家管理系统控制器
 * 
 * @author cencat
 * @date 2024-01-20
 */
@Tag(name = "固定商家管理", description = "固定商家管理系统核心功能接口")
@RestController
@RequestMapping("/merchant")
@RequiredArgsConstructor
@Validated
public class MerchantController extends BaseController {

    private final IMerchantService merchantService;
    private final IMerchantDriverService merchantDriverService;
    private final IMerchantOrderService merchantOrderService;

    /**
     * 查询商家列表
     */
    @Operation(summary = "查询商家列表", description = "分页查询商家信息")
    @PreAuthorize("@ss.hasPermi('merchant:list')")
    @GetMapping("/list")
    public TableDataInfo list(Merchant merchant) {
        startPage();
        List<Merchant> list = merchantService.selectMerchantList(merchant);
        return getDataTable(list);
    }

    /**
     * 获取商家详情
     */
    @Operation(summary = "获取商家详情", description = "根据商家ID获取详细信息")
    @PreAuthorize("@ss.hasPermi('merchant:query')")
    @GetMapping(value = "/{merchantId}")
    public AjaxResult getInfo(@Parameter(description = "商家ID") @PathVariable Long merchantId) {
        MerchantVO merchantVO = merchantService.getMerchantDetail(merchantId);
        return success(merchantVO);
    }

    /**
     * 新增商家
     */
    @Operation(summary = "新增商家", description = "创建新的商家信息")
    @PreAuthorize("@ss.hasPermi('merchant:add')")
    @Log(title = "商家管理", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@Valid @RequestBody MerchantCreateDTO createDTO) {
        MerchantVO merchantVO = merchantService.createMerchant(createDTO);
        return success(merchantVO);
    }

    /**
     * 修改商家
     */
    @Operation(summary = "修改商家", description = "更新商家信息")
    @PreAuthorize("@ss.hasPermi('merchant:edit')")
    @Log(title = "商家管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Valid @RequestBody MerchantUpdateDTO updateDTO) {
        boolean result = merchantService.updateMerchant(updateDTO);
        return toAjax(result);
    }

    /**
     * 删除商家
     */
    @Operation(summary = "删除商家", description = "删除指定商家")
    @PreAuthorize("@ss.hasPermi('merchant:remove')")
    @Log(title = "商家管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{merchantIds}")
    public AjaxResult remove(@Parameter(description = "商家ID数组") @PathVariable Long[] merchantIds) {
        boolean result = merchantService.deleteMerchantByIds(merchantIds);
        return toAjax(result);
    }

    /**
     * 启用/禁用商家
     */
    @Operation(summary = "启用禁用商家", description = "启用或禁用商家账户")
    @PreAuthorize("@ss.hasPermi('merchant:status')")
    @Log(title = "商家管理", businessType = BusinessType.UPDATE)
    @PutMapping("/status")
    public AjaxResult changeStatus(@RequestParam Long merchantId,
                                  @RequestParam String status,
                                  @RequestParam(required = false) String remark) {
        boolean result = merchantService.updateMerchantStatus(merchantId, status, remark);
        return toAjax(result);
    }

    /**
     * 商家认证
     */
    @Operation(summary = "商家认证", description = "商家资质认证审核")
    @PreAuthorize("@ss.hasPermi('merchant:auth')")
    @Log(title = "商家认证", businessType = BusinessType.UPDATE)
    @PostMapping("/authenticate")
    public AjaxResult authenticate(@RequestParam Long merchantId,
                                  @RequestParam String authStatus,
                                  @RequestParam(required = false) String authRemark) {
        boolean result = merchantService.authenticateMerchant(merchantId, authStatus, authRemark);
        return toAjax(result);
    }

    /**
     * 商家司机绑定管理
     */
    @Operation(summary = "绑定司机", description = "为商家绑定专属司机")
    @PreAuthorize("@ss.hasPermi('merchant:driver:bind')")
    @Log(title = "司机绑定", businessType = BusinessType.INSERT)
    @PostMapping("/bind-driver")
    public AjaxResult bindDriver(@Valid @RequestBody MerchantDriverBindDTO bindDTO) {
        MerchantDriver merchantDriver = merchantDriverService.bindDriver(bindDTO);
        return success("绑定成功", merchantDriver.getId());
    }

    /**
     * 解绑司机
     */
    @Operation(summary = "解绑司机", description = "解除商家与司机的绑定关系")
    @PreAuthorize("@ss.hasPermi('merchant:driver:unbind')")
    @Log(title = "司机解绑", businessType = BusinessType.DELETE)
    @PostMapping("/unbind-driver")
    public AjaxResult unbindDriver(@RequestParam Long merchantId,
                                  @RequestParam Long driverId,
                                  @RequestParam(required = false) String reason) {
        boolean result = merchantDriverService.unbindDriver(merchantId, driverId, reason);
        return toAjax(result);
    }

    /**
     * 查询商家绑定司机列表
     */
    @Operation(summary = "绑定司机列表", description = "查询商家绑定的司机列表")
    @PreAuthorize("@ss.hasPermi('merchant:driver:list')")
    @GetMapping("/bound-drivers/{merchantId}")
    public TableDataInfo getBoundDrivers(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                        @RequestParam(required = false) String status) {
        startPage();
        List<MerchantDriver> list = merchantDriverService.getBoundDrivers(merchantId, status);
        return getDataTable(list);
    }

    /**
     * 更新司机绑定状态
     */
    @Operation(summary = "更新绑定状态", description = "更新商家司机绑定状态")
    @PreAuthorize("@ss.hasPermi('merchant:driver:status')")
    @Log(title = "绑定状态", businessType = BusinessType.UPDATE)
    @PutMapping("/driver-bind-status")
    public AjaxResult updateBindStatus(@RequestParam Long bindId,
                                      @RequestParam String status,
                                      @RequestParam(required = false) String remark) {
        boolean result = merchantDriverService.updateBindStatus(bindId, status, remark);
        return toAjax(result);
    }

    /**
     * 司机工作时间设置
     */
    @Operation(summary = "设置工作时间", description = "设置绑定司机的工作时间")
    @PreAuthorize("@ss.hasPermi('merchant:driver:schedule')")
    @Log(title = "工作时间", businessType = BusinessType.UPDATE)
    @PostMapping("/set-work-schedule")
    public AjaxResult setWorkSchedule(@RequestParam Long bindId,
                                     @RequestParam String workDays,
                                     @RequestParam String startTime,
                                     @RequestParam String endTime,
                                     @RequestParam(required = false) String breakTime) {
        boolean result = merchantDriverService.setWorkSchedule(bindId, workDays, startTime, endTime, breakTime);
        return toAjax(result);
    }

    /**
     * 快捷下单
     */
    @Operation(summary = "快捷下单", description = "商家快捷创建配送订单")
    @PreAuthorize("@ss.hasPermi('merchant:order:quick')")
    @Log(title = "快捷下单", businessType = BusinessType.INSERT)
    @PostMapping("/quick-order")
    public AjaxResult quickOrder(@Valid @RequestBody QuickOrderDTO quickOrderDTO) {
        MerchantOrder order = merchantOrderService.createQuickOrder(quickOrderDTO);
        return success("下单成功", order.getId());
    }

    /**
     * 查询商家订单列表
     */
    @Operation(summary = "商家订单列表", description = "查询商家的配送订单")
    @PreAuthorize("@ss.hasPermi('merchant:order:list')")
    @GetMapping("/orders/{merchantId}")
    public TableDataInfo getMerchantOrders(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                          @RequestParam(required = false) String status,
                                          @RequestParam(required = false) String startDate,
                                          @RequestParam(required = false) String endDate) {
        startPage();
        List<MerchantOrder> list = merchantOrderService.getMerchantOrders(merchantId, status, startDate, endDate);
        return getDataTable(list);
    }

    /**
     * 取消订单
     */
    @Operation(summary = "取消订单", description = "商家取消配送订单")
    @PreAuthorize("@ss.hasPermi('merchant:order:cancel')")
    @Log(title = "取消订单", businessType = BusinessType.UPDATE)
    @PostMapping("/cancel-order")
    public AjaxResult cancelOrder(@RequestParam Long orderId,
                                 @RequestParam Long merchantId,
                                 @RequestParam String reason) {
        boolean result = merchantOrderService.cancelOrder(orderId, merchantId, reason);
        return toAjax(result);
    }

    /**
     * 修改订单
     */
    @Operation(summary = "修改订单", description = "商家修改配送订单信息")
    @PreAuthorize("@ss.hasPermi('merchant:order:edit')")
    @Log(title = "修改订单", businessType = BusinessType.UPDATE)
    @PutMapping("/order")
    public AjaxResult editOrder(@RequestParam Long orderId,
                               @RequestParam Long merchantId,
                               @RequestBody Map<String, Object> orderData) {
        boolean result = merchantOrderService.editOrder(orderId, merchantId, orderData);
        return toAjax(result);
    }

    /**
     * 商家配送分析
     */
    @Operation(summary = "配送分析", description = "商家配送数据分析")
    @PreAuthorize("@ss.hasPermi('merchant:analysis')")
    @GetMapping("/delivery-analysis/{merchantId}")
    public AjaxResult getDeliveryAnalysis(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                         @RequestParam(required = false) String startDate,
                                         @RequestParam(required = false) String endDate,
                                         @RequestParam(required = false) String analysisType) {
        MerchantAnalysisVO analysis = merchantService.getDeliveryAnalysis(merchantId, startDate, endDate, analysisType);
        return success(analysis);
    }

    /**
     * 商家统计信息
     */
    @Operation(summary = "商家统计", description = "获取商家统计数据")
    @PreAuthorize("@ss.hasPermi('merchant:statistics')")
    @GetMapping("/statistics/{merchantId}")
    public AjaxResult getStatistics(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                   @RequestParam(required = false) String startDate,
                                   @RequestParam(required = false) String endDate,
                                   @RequestParam(required = false) String dimension) {
        MerchantStatisticsVO statistics = merchantService.getMerchantStatistics(merchantId, startDate, endDate, dimension);
        return success(statistics);
    }

    /**
     * 商家收入分析
     */
    @Operation(summary = "收入分析", description = "分析商家收入情况")
    @PreAuthorize("@ss.hasPermi('merchant:revenue')")
    @GetMapping("/revenue-analysis/{merchantId}")
    public AjaxResult getRevenueAnalysis(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                        @RequestParam(required = false) String startDate,
                                        @RequestParam(required = false) String endDate,
                                        @RequestParam(required = false) String groupBy) {
        Map<String, Object> analysis = merchantService.getRevenueAnalysis(merchantId, startDate, endDate, groupBy);
        return success(analysis);
    }

    /**
     * 商家成本分析
     */
    @Operation(summary = "成本分析", description = "分析商家配送成本")
    @PreAuthorize("@ss.hasPermi('merchant:cost')")
    @GetMapping("/cost-analysis/{merchantId}")
    public AjaxResult getCostAnalysis(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                     @RequestParam(required = false) String startDate,
                                     @RequestParam(required = false) String endDate,
                                     @RequestParam(required = false) String costType) {
        Map<String, Object> analysis = merchantService.getCostAnalysis(merchantId, startDate, endDate, costType);
        return success(analysis);
    }

    /**
     * 商家效率分析
     */
    @Operation(summary = "效率分析", description = "分析商家配送效率")
    @PreAuthorize("@ss.hasPermi('merchant:efficiency')")
    @GetMapping("/efficiency-analysis/{merchantId}")
    public AjaxResult getEfficiencyAnalysis(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                           @RequestParam(required = false) String startDate,
                                           @RequestParam(required = false) String endDate,
                                           @RequestParam(required = false) String metricType) {
        Map<String, Object> analysis = merchantService.getEfficiencyAnalysis(merchantId, startDate, endDate, metricType);
        return success(analysis);
    }

    /**
     * 商家评价管理
     */
    @Operation(summary = "评价管理", description = "管理商家配送评价")
    @PreAuthorize("@ss.hasPermi('merchant:evaluation')")
    @GetMapping("/evaluations/{merchantId}")
    public TableDataInfo getEvaluations(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                       @RequestParam(required = false) String startDate,
                                       @RequestParam(required = false) String endDate,
                                       @RequestParam(required = false) Integer minRating,
                                       @RequestParam(required = false) Integer maxRating) {
        startPage();
        List<Map<String, Object>> list = merchantService.getEvaluations(merchantId, startDate, endDate, minRating, maxRating);
        return getDataTable(list);
    }

    /**
     * 回复评价
     */
    @Operation(summary = "回复评价", description = "商家回复客户评价")
    @PreAuthorize("@ss.hasPermi('merchant:evaluation:reply')")
    @Log(title = "评价回复", businessType = BusinessType.UPDATE)
    @PostMapping("/reply-evaluation")
    public AjaxResult replyEvaluation(@RequestParam Long evaluationId,
                                     @RequestParam Long merchantId,
                                     @RequestParam String replyContent) {
        boolean result = merchantService.replyEvaluation(evaluationId, merchantId, replyContent);
        return toAjax(result);
    }

    /**
     * 商家设置管理
     */
    @Operation(summary = "商家设置", description = "管理商家系统设置")
    @PreAuthorize("@ss.hasPermi('merchant:settings')")
    @Log(title = "商家设置", businessType = BusinessType.UPDATE)
    @PostMapping("/settings")
    public AjaxResult updateSettings(@RequestParam Long merchantId,
                                    @RequestBody Map<String, Object> settings) {
        boolean result = merchantService.updateSettings(merchantId, settings);
        return toAjax(result);
    }

    /**
     * 获取商家设置
     */
    @Operation(summary = "获取商家设置", description = "获取商家系统设置")
    @PreAuthorize("@ss.hasPermi('merchant:settings:query')")
    @GetMapping("/settings/{merchantId}")
    public AjaxResult getSettings(@Parameter(description = "商家ID") @PathVariable Long merchantId) {
        Map<String, Object> settings = merchantService.getSettings(merchantId);
        return success(settings);
    }

    /**
     * 商家通知管理
     */
    @Operation(summary = "发送通知", description = "向商家发送系统通知")
    @PreAuthorize("@ss.hasPermi('merchant:notify')")
    @Log(title = "商家通知", businessType = BusinessType.INSERT)
    @PostMapping("/notify")
    public AjaxResult sendNotification(@RequestParam Long merchantId,
                                      @RequestParam String notifyType,
                                      @RequestParam String title,
                                      @RequestParam String content,
                                      @RequestParam(required = false) String extraData) {
        boolean result = merchantService.sendNotification(merchantId, notifyType, title, content, extraData);
        return toAjax(result);
    }

    /**
     * 批量发送通知
     */
    @Operation(summary = "批量发送通知", description = "向多个商家批量发送通知")
    @PreAuthorize("@ss.hasPermi('merchant:notify:batch')")
    @Log(title = "批量通知", businessType = BusinessType.INSERT)
    @PostMapping("/batch-notify")
    public AjaxResult batchNotify(@RequestParam Long[] merchantIds,
                                 @RequestParam String notifyType,
                                 @RequestParam String title,
                                 @RequestParam String content) {
        boolean result = merchantService.batchNotify(merchantIds, notifyType, title, content);
        return toAjax(result);
    }

    /**
     * 商家账单管理
     */
    @Operation(summary = "商家账单", description = "查询商家配送账单")
    @PreAuthorize("@ss.hasPermi('merchant:bill')")
    @GetMapping("/bills/{merchantId}")
    public TableDataInfo getBills(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                 @RequestParam(required = false) String startDate,
                                 @RequestParam(required = false) String endDate,
                                 @RequestParam(required = false) String billType,
                                 @RequestParam(required = false) String status) {
        startPage();
        List<Map<String, Object>> list = merchantService.getBills(merchantId, startDate, endDate, billType, status);
        return getDataTable(list);
    }

    /**
     * 生成账单
     */
    @Operation(summary = "生成账单", description = "为商家生成配送账单")
    @PreAuthorize("@ss.hasPermi('merchant:bill:generate')")
    @Log(title = "生成账单", businessType = BusinessType.INSERT)
    @PostMapping("/generate-bill")
    public AjaxResult generateBill(@RequestParam Long merchantId,
                                  @RequestParam String billPeriod,
                                  @RequestParam(required = false) String billType) {
        Map<String, Object> bill = merchantService.generateBill(merchantId, billPeriod, billType);
        return success(bill);
    }

    /**
     * 商家数据导出
     */
    @Operation(summary = "导出商家数据", description = "导出商家信息到Excel")
    @PreAuthorize("@ss.hasPermi('merchant:export')")
    @Log(title = "商家管理", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Merchant merchant) {
        List<Merchant> list = merchantService.selectMerchantList(merchant);
        ExcelUtil<Merchant> util = new ExcelUtil<Merchant>(Merchant.class);
        util.exportExcel(response, list, "商家数据");
    }

    /**
     * 商家数据导入
     */
    @Operation(summary = "导入商家数据", description = "从Excel导入商家信息")
    @PreAuthorize("@ss.hasPermi('merchant:import')")
    @Log(title = "商家管理", businessType = BusinessType.IMPORT)
    @PostMapping("/import")
    public AjaxResult importData(MultipartFile file) throws Exception {
        ExcelUtil<Merchant> util = new ExcelUtil<Merchant>(Merchant.class);
        List<Merchant> merchantList = util.importExcel(file.getInputStream());
        String message = merchantService.importMerchants(merchantList);
        return success(message);
    }

    /**
     * 商家区域管理
     */
    @Operation(summary = "设置服务区域", description = "设置商家服务区域范围")
    @PreAuthorize("@ss.hasPermi('merchant:area')")
    @Log(title = "服务区域", businessType = BusinessType.UPDATE)
    @PostMapping("/set-service-area")
    public AjaxResult setServiceArea(@RequestParam Long merchantId,
                                    @RequestParam String areaType,
                                    @RequestParam String areaData,
                                    @RequestParam(required = false) String areaName) {
        boolean result = merchantService.setServiceArea(merchantId, areaType, areaData, areaName);
        return toAjax(result);
    }

    /**
     * 获取服务区域
     */
    @Operation(summary = "获取服务区域", description = "获取商家服务区域信息")
    @PreAuthorize("@ss.hasPermi('merchant:area:query')")
    @GetMapping("/service-area/{merchantId}")
    public AjaxResult getServiceArea(@Parameter(description = "商家ID") @PathVariable Long merchantId) {
        Map<String, Object> serviceArea = merchantService.getServiceArea(merchantId);
        return success(serviceArea);
    }

    /**
     * 商家优惠管理
     */
    @Operation(summary = "设置优惠活动", description = "设置商家配送优惠活动")
    @PreAuthorize("@ss.hasPermi('merchant:promotion')")
    @Log(title = "优惠活动", businessType = BusinessType.INSERT)
    @PostMapping("/set-promotion")
    public AjaxResult setPromotion(@RequestParam Long merchantId,
                                  @RequestParam String promotionType,
                                  @RequestParam String promotionName,
                                  @RequestParam String promotionRule,
                                  @RequestParam String startTime,
                                  @RequestParam String endTime) {
        Map<String, Object> promotion = merchantService.setPromotion(merchantId, promotionType, promotionName, promotionRule, startTime, endTime);
        return success(promotion);
    }

    /**
     * 商家性能监控
     */
    @Operation(summary = "性能监控", description = "监控商家系统性能")
    @PreAuthorize("@ss.hasPermi('merchant:monitor')")
    @GetMapping("/performance-monitor/{merchantId}")
    public AjaxResult getPerformanceMonitor(@Parameter(description = "商家ID") @PathVariable Long merchantId,
                                           @RequestParam(required = false) String metricType) {
        Map<String, Object> performance = merchantService.getPerformanceMonitor(merchantId, metricType);
        return success(performance);
    }

    /**
     * 商家健康检查
     */
    @Operation(summary = "健康检查", description = "检查商家系统健康状态")
    @PreAuthorize("@ss.hasPermi('merchant:health')")
    @GetMapping("/health-check/{merchantId}")
    public AjaxResult healthCheck(@Parameter(description = "商家ID") @PathVariable Long merchantId) {
        Map<String, Object> healthStatus = merchantService.healthCheck(merchantId);
        return success(healthStatus);
    }

    /**
     * 批量更新商家状态
     */
    @Operation(summary = "批量更新状态", description = "批量更新多个商家的状态")
    @PreAuthorize("@ss.hasPermi('merchant:batch:status')")
    @Log(title = "商家管理", businessType = BusinessType.UPDATE)
    @PutMapping("/batch-status")
    public AjaxResult batchUpdateStatus(@RequestParam Long[] merchantIds,
                                       @RequestParam String status,
                                       @RequestParam(required = false) String remark) {
        boolean result = merchantService.batchUpdateStatus(merchantIds, status, remark);
        return toAjax(result);
    }
}